package org.SSV.NLES.client;

import com.bouwkamp.gwt.user.client.ui.RoundedPanel;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

import org.me.client.AnalisierteFunktion;
import org.me.client.FehlungDerFunktionenReihe;
import org.me.client.FehlungDerVariable;
import org.me.client.FunktionenReihe;
import org.me.client.NumerischeMethoden;
import org.me.client.NumerischeOperationen;
import org.me.client.NummerMatrix;
import org.me.client.RecursiveDescentParser;
import org.me.client.Variable;
import org.me.client.VariablenReihe;

import java.util.ArrayList;

public class NLES_Gui implements EntryPoint, ClickListener, KeyboardListener {
	// <decs>
	RecursiveDescentParser parser = new RecursiveDescentParser("");

	DockPanel main = new DockPanel();

	RoundedPanel roundedMain = new RoundedPanel(main);

	HTML instructs = new HTML(
			"<html><body> <h1> NLES </h1> <p>Bitte Ihnen, druecken Sie die Kaesten</p> </body></html>");

	HorizontalPanel varFlaeche = new HorizontalPanel();

	VerticalPanel funktionenFlaeche = new VerticalPanel();

	HorizontalPanel solnFlaeche = new HorizontalPanel();

	VerticalPanel buttonFlaeche = new VerticalPanel();

	Button button_neuesVar = new Button(" Var++ ");

	Button button_varSchlagen = new Button(" Var-- ");

	Button button_dem = new Button(" Dem ");

	Button button_S = new Button("S");

	Button button_N = new Button("N");

	ArrayList variablen = new ArrayList();

	Label console = new Label("Cons");

	LabelTextBoxPanel sTypischeWert = new LabelTextBoxPanel("Typ", "2.0", "S",
			"2cm", "RoundedPanel");

	int N = 0;

	// </decs>
	public void onModuleLoad() {
		// <button_*>
		button_neuesVar.addClickListener(this);
		button_S.addClickListener(this);
		button_dem.addClickListener(this);
		button_varSchlagen.addClickListener(this);
		// </button_*>

		// <console>
		console.setVisible(false);
		// </console>

		// <buttonFlaeche>
		buttonFlaeche.add(sTypischeWert);
		buttonFlaeche.add(button_neuesVar);
		buttonFlaeche.add(button_varSchlagen);
		buttonFlaeche.add(button_S);
		buttonFlaeche.add(button_dem);
		buttonFlaeche.add(button_N);
		buttonFlaeche.setHorizontalAlignment(HasAlignment.ALIGN_CENTER);
		buttonFlaeche.setSpacing(3);
		// </buttonFlaeche>

		// <varFlaeche>
		varFlaeche.add(new Label(" Var:X= \n (est)"));
		varFlaeche.setSpacing(3);
		// </varFlaeche>

		// <funktionenFlaeche>
		funktionenFlaeche.add(new Label(" Funkt "));
		funktionenFlaeche.setSpacing(3);
		// </funktionenFlaeche>

		// <main>
		main.add(new RoundedPanel(varFlaeche), DockPanel.NORTH);
		main.add(new RoundedPanel(instructs), DockPanel.WEST);
		main.add(buttonFlaeche, DockPanel.WEST);
		main.add(console, DockPanel.EAST);
		main.add(new RoundedPanel(solnFlaeche), DockPanel.EAST);
		main.add(funktionenFlaeche, DockPanel.CENTER);
		main.setSpacing(3);
		// </main>

		// <Rootpanel>
		onClick(button_neuesVar);
		RootPanel.get().setStyleName("myStyles");
		RootPanel.get("slot1").add(roundedMain);

		// </Rootpanel>
	}

	public void variablenSetzen() {
		variablen.clear();

		for (int i = 0; i < N; i++) {
			variablen
					.add(i, new Variable("x", i + 1,
							new RecursiveDescentParser(
									((LabelTextBoxPanel) (varFlaeche
											.getWidget(i + 1))).getTextbox()
											.getText()).eval()));
		}
	}

	public void onClick(Widget sender) {
		// TODO Auto-generated method stub
		if (sender == button_neuesVar) {
			N++;

			final LabelTextBoxPanel temp_panel_x = (new LabelTextBoxPanel("x["
					+ Integer.toString(N) + "]", sTypischeWert.getTextbox()
					.getText()
					+ "/" + (2 * varFlaeche.getWidgetCount()), "S", "1cm",
					"RoundedPanel"));
			final LabelTextBoxPanel temp_panel_f = new LabelTextBoxPanel("f["
					+ N + "](X)=0= ", "acos cos 1/2*x["
					+ new Integer(varFlaeche.getWidgetCount() - 1).toString()
					+ "]", "OE", "5cm", "RoundedPanel");
			temp_panel_f.getTextbox().addKeyboardListener(this);
			temp_panel_x.getTextbox().addKeyboardListener(this);
			varFlaeche.add(temp_panel_x);
			funktionenFlaeche.add(temp_panel_f);
		}

		if ((sender == button_varSchlagen) && (N > 0)) {
			varFlaeche.remove(N);
			funktionenFlaeche.remove(N);
			N--;
		}

		if (sender == button_S) {
			variablenSetzen();

			final Variable[] variablen_ = new Variable[N];
			final String[] funktionenStraenge = new String[N];
			FunktionenReihe sSystem;

			for (int i = 0; i < N; i++) {
				variablen_[i] = (Variable) variablen.get(i);
				funktionenStraenge[i] = ((LabelTextBoxPanel) (funktionenFlaeche
						.getWidget(i + 1))).getTextbox().getText();
			}

			console.setVisible(true);
			try {
				sSystem = new FunktionenReihe(funktionenStraenge, variablen_);
				console.setText("Cons\n");
				for (int i = 0; i < funktionenStraenge.length; i++) {
					console.setText(console.getText() + "\n"
							+ sSystem.funktionenAbzuschaetzen().sElementGeben(i, 0));
				}
			} catch (FehlungDerFunktionenReihe e) {
				console.setText(e.getMessage());
			}
		}
		if (sender == button_dem) {
			NummerMatrix C = NumerischeMethoden.Identitaet(4);
			NummerMatrix A = NumerischeMethoden.produkt(C, C);
			A = NumerischeMethoden.umzustellen(A);
			A = NumerischeMethoden.produkt(new Double(-1), A);
			console.setText("Cons"
					+ NumerischeMethoden.druecken(A, 5, 3, false,
							new char[] { '[', ']' }));
		}
	}

	public void onKeyDown(Widget sender, char keyCode, int modifiers) {
		// TODO Auto-generated method stub
	}

	public void onKeyPress(Widget sender, char keyCode, int modifiers) {
		// TODO Auto-generated method stub
	}

	public void onKeyUp(Widget sender, char keyCode, int modifiers) {
		if (keyCode == KeyboardListener.KEY_ENTER) {
			onClick(button_S);
		}
	}
}
